package org.je.json;

import org.je.ufo.Int;
import org.je.util.CharUtil;

class InnerUtil
{

	static String getName(String source, Int offset) {
		char start = source.charAt(offset.val());
		if (!CharUtil.isNameStartChar(start))
			throw new RuntimeException("illegal-char-of-start-name\r\n" + ES(source, offset.val()));
		// ++offset[0];
		offset.increase();
		StringBuilder bf = new StringBuilder();
		bf.append(start);

		for (int i = offset.val(); i < source.length(); ++i) {
			char c = source.charAt(i);
			if (CharUtil.isNameChar(c)) {
				bf.append(c);
			} else if (CharUtil.isBlank(c) || c == ':') {
				// offset[0] = i;
				offset.val(i);
				return bf.toString();
			} else {
				throw new RuntimeException("illegal-name-char\r\n" + ES(source, offset.val()));
			}
		}
		throw new RuntimeException("illegal-end-of-name\r\n" + ES(source, offset.val()));
	}

	/**
	 * * 调用这个方法之后，offset 指向字符串结尾标示符 可能是Key也可能是Value
	 */
	static String getString(String source, Int offset) {
		char symbol = source.charAt(offset.val());
		StringBuilder bf = new StringBuilder();
		for (int i = offset.val() + 1; i < source.length(); ++i) {
			char c = source.charAt(i);
			if (c == symbol) {
				// offset[0] = i + 1;
				offset.val(i + 1);
				return bf.toString();
			}
			if (c == '\\') {
				if (i == source.length() - 1)
					throw new RuntimeException("string-is-not-finished\r\n" + ES(source, offset.val()));
				char nx = source.charAt(i + 1);
				if (nx == 't') {
					bf.append('\t');
				} else if (nx == 'r') {
					bf.append('\r');
				} else if (nx == 'n') {
					bf.append('\n');
				} else {
					bf.append(nx);
				}
				++i;
			} else {
				bf.append(c);
			}
		}
		throw new RuntimeException("string-is-not-finished\r\n" + ES(source, offset.val()));
	}

	/***
	 * 只可能出现在Value
	 */
	static String getNum(String source, Int offset) {
		char start = source.charAt(offset.val());

		StringBuilder bf = new StringBuilder();
		bf.append(start);
		if (start == '-') {
			if (offset.val() == source.length() - 1)
				throw new RuntimeException("illegal-char-of-number\r\n" + ES(source, offset.val()));
			// ++offset[0];
			offset.increase();
			start = source.charAt(offset.val());
			if (!CharUtil.isNum(start))
				throw new RuntimeException("illegal-char-of-number\r\n" + ES(source, offset.val()));

			bf.append(start);
		}
		boolean findPoint = false;
		for (int i = offset.val() + 1; i < source.length(); ++i) {
			char c = source.charAt(i);
			if (CharUtil.isNum(c)) {
				bf.append(c);
			} else if ('.' == c && findPoint == false) {
				findPoint = true;
				bf.append(c);
			} else if (c == ',' || c == '}' || c == ']' || CharUtil.isBlank(c)) {
				// offset[0] = i;
				offset.val(i);
				return bf.toString();
			} else {
				throw new RuntimeException("illegal-char-of-number:[" + c + "]\r\n" + ES(source, offset.val()));
			}
		}
		throw new RuntimeException("json-finished-error\r\n" + ES(source, offset.val()));
	}

	static char point2nonblank(String source, Int offset) {
		for (int i = offset.val(); i < source.length(); ++i) {
			char c = source.charAt(i);
			if (!CharUtil.isBlank(c)) {
				// offset.val() = i;
				offset.val(i);
				return c;
			}
		}
		throw new RuntimeException("can-not-find-nonblank\r\n" + ES(source, offset.val()));
	}

	static String ES(String source, int off) {
		if (off <= 0)
			return source;
		return source.substring(0, off) + "\r\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n" + source.substring(off);
	}
}
